﻿/*
 * LibMediaCaster.h
 *
 *  Created on: 2016年6月20日
 *      Author: terry
 */

#ifndef LIBMEDIACASTER_H_
#define LIBMEDIACASTER_H_


////////////////////////////////////////////////////////////////////////////

#ifdef WIN32

    #ifndef NOMINMAX
    #define NOMINMAX
    #endif //NOMINMAX

	#include <Windows.h>
#else

#endif //WIN32


////////////////////////////////////////////////////////////////////////////

#ifdef _MSC_VER
    typedef signed char     int8_t;
    typedef unsigned char   uint8_t;
    typedef short           int16_t;
    typedef unsigned short  uint16_t;
    typedef int             int32_t;
    typedef unsigned        uint32_t;
    typedef long long       int64_t;
    typedef unsigned long long   uint64_t;
#else
    #include <stdint.h>
    typedef void*   HANDLE;
#endif //_MSC_VER


///////////////////////////////////////////////////////////////////
#ifdef WIN32
    #ifndef DLLEXPORT
    #define DLLEXPORT __declspec(dllexport)
    #endif //DLLEXPORT
#else
    #define DLLEXPORT __attribute__ ((visibility ("default")))
#endif //WIN32

///////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C"
{
#endif

/////////////////////////////////////////////////////////////////////////////
#ifndef MKBETAG
#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24))
#endif //MKBETAG


/// 编码
enum MCodec
{
    MCODEC_NONE = 0,

    MCODEC_H264 = 28,
	MCODEC_HEVC = MKBETAG('H','2','6','5'), /// H.265
	MCODEC_H265 = MCODEC_HEVC,

    MCODEC_G711U = 65542,
    MCODEC_G711A,

    MCODEC_MP3 = 0x15001,
    MCODEC_AAC = 0x15002,
    MCODEC_AC3 = 0x15003,
    MCODEC_VORBIS = 0x15005,

	MCODEC_RAW = 0x10101010

};

/// 媒体格式
struct MFormat
{
	int codec;		/// 视频编码  @see MCodec
	int width;		/// 视频高
	int height;		/// 视频宽
	int framerate;		/// 帧率
	int profile;
    int clockRate;  /// 时钟频率

	int audioCodec;	/// 音频编码  @see MCodec
	int channels;	/// 通道数
	int sampleRate;	/// 采样率
	int audioProfile;	/// 档次
    int audioRate;      /// 音频时钟频率

	int vPropSize;		/// 视频解码参数, 对于H.264是sps+pps, 对于H.265是vps+sps+pps
	unsigned char* vProp;

};

enum MType
{
    MTYPE_NONE  = -1,
    MTYPE_VIDEO = 0,
    MTYPE_AUDIO,
    MTYPE_DATA,
};


/// 媒体包
struct MPacket
{
    int type;       /// 
	uint8_t* data;	/// 数据指针
	int size;		/// 数据长度
	int64_t pts;	/// 时间戳
	int duration;	/// 时长
	int flags;		/// 标识
};

enum MCasterEventType
{
	MCASTER_SESSION_REQUEST = 1,
	MCASTER_SESSION_CREATE,
	MCASTER_SESSION_DESTROY,
};

struct MCasterEvent
{
    int  type;
    HANDLE  handle;	/// 通道句柄
    char streamName[256];	/// 通道名称
};


enum MCasterProtocol
{
	MCASTER_PROTOCOL_TCP,
	MCASTER_PROTOCOL_UDT,
    MCASTER_PROTOCOL_MTP,
	MCASTER_PROTOCOL_UMSG,
	MCASTER_PROTOCOL_RTSP,

};

/////////////////////////////////////////////////////////////////////////////

/**
 * 初始化
 * @return
 */
DLLEXPORT int mcaster_init();

/**
 *
 */
DLLEXPORT void mcaster_quit();

/**
 * 启动指定协议的媒体服务
 * @param protocol	协议 @see MCasterProtocol
 * @param ip		地址
 * @param port		端口
 * @param params	参数
 * @return 0 表示成功
 */
DLLEXPORT int mcaster_start(int protocol, const char* ip, int port, const char* params);

/**
 * 停止指定协议的媒体服务
 * @param protocol
 * @return
 */
DLLEXPORT int mcaster_stop(int protocol);

/**
 * 判断媒体服务是否启动
 * @param protocol
 * @return
 */
DLLEXPORT int mcaster_isStarted(int protocol);

/**
 * 停止所有媒体服务
 */
DLLEXPORT void mcaster_stopAll();

/**
 * 创建媒体分发
 * @param handle	媒体分发句柄
 * @param name		名称
 * @param fmt		媒体格式
 * @return
 */
DLLEXPORT int mcaster_open(HANDLE* handle, const char* name, const MFormat* fmt);

/**
 * 关闭媒体分发
 * @param handle	媒体分发句柄
 * @return
 */
DLLEXPORT int mcaster_close(HANDLE handle);

/**
 * 关闭所有的媒体分发
 */
DLLEXPORT void mcaster_closeAll();

/**
 * 查找媒体分发
 * @param name
 * @return
 */
DLLEXPORT HANDLE mcaster_find(const char* name);

/**
 * 设置媒体格式
 * @param handle
 * @param fmt	媒体格式
 * @return
 */
DLLEXPORT int mcaster_setFormat(HANDLE handle, const MFormat* fmt);

/**
 * 获取媒体格式
 * @param handle
 * @param fmt	媒体格式
 * @return
 */
DLLEXPORT int mcaster_getFormat(HANDLE handle, MFormat* fmt);

/**
 * 写入媒体包
 * @param handle	媒体分发句柄
 * @param pkt		媒体包
 * @return
 */
DLLEXPORT int mcaster_write(HANDLE handle, const MPacket* pkt);



/**
 * 事件回调函数
 * @param event		事件
 * @param context	回调环境
 */
typedef void (*MCasterEventCallback)(const MCasterEvent* event, int protocol, void* context);


/**
 * 设置事件回调句柄
 * @param cb		回调函数指针
 * @param context	回调环境
 */
DLLEXPORT void mcaster_setCallback(MCasterEventCallback cb, void* context);

/**
 * 设置缓冲区最大时长, 单位为毫秒
 * @param ms
 */
DLLEXPORT void mcaster_setQueueDuration(int ms);

/**
 * 设置socket发送缓冲区大小
 * @param size
 */
DLLEXPORT void mcaster_setSendBufSize(int size);

/////////////////////////////////////////////////////////////////////////////

#ifdef __cplusplus
}
#endif


#endif /* LIBMEDIACASTER_H_ */
